home *** CD-ROM | disk | FTP | other *** search
/ Workbench Design / WB Collection.iso / workbench werkzeuge / uhren & terminkalender / time / wbclock / wbclock.c < prev    next >
C/C++ Source or Header  |  1996-04-07  |  10KB  |  427 lines

  1. #include <proto/exec.h>
  2. #include <proto/dos.h>
  3. #include <proto/wb.h>
  4. #include <proto/icon.h>
  5. #include <proto/intuition.h>
  6.  
  7. #include <exec/devices.h>
  8. #include <devices/timer.h>
  9. #include <workbench/startup.h>
  10. #include <intuition/intuition.h>
  11.  
  12. #include <dos/dos.h>
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <math.h>
  17.  
  18. #include "evtypes.h"
  19.  
  20. void error(char *s)
  21. {
  22.     struct EasyStruct es;
  23.     
  24.     es.es_StructSize = sizeof(es);
  25.     es.es_Flags = 0;
  26.     es.es_Title = "WB Clock";
  27.     es.es_TextFormat = s;
  28.     es.es_GadgetFormat = "Ok";
  29.     
  30.     EasyRequest(0, &es, 0, 0);
  31. }
  32.  
  33. struct DiskObject *wb_disk_object(struct WBStartup *wbs)
  34. {
  35.     struct WBArg *wba;
  36.     BPTR olddir;
  37.     struct DiskObject *dobj;
  38.     
  39.     wba = wbs->sm_ArgList;
  40.     olddir = CurrentDir(wba[0].wa_Lock);
  41.     dobj = GetDiskObject(wba[0].wa_Name);
  42.     CurrentDir(olddir);
  43.     
  44.     return dobj;
  45. }
  46.  
  47. void wb_put_disk_object(struct WBStartup *wbs, struct DiskObject *dobj)
  48. {
  49.     struct WBArg *wba;
  50.     BPTR olddir;
  51.     
  52.     wba = wbs->sm_ArgList;
  53.     olddir = CurrentDir(wba[0].wa_Lock);
  54.     PutDiskObject(wba[0].wa_Name, dobj);
  55.     CurrentDir(olddir);
  56.     
  57.     return;
  58. }
  59.  
  60. typedef struct {
  61.     unsigned short *d;
  62.     unsigned short width, height, ww;
  63. } drawsurface;
  64.  
  65. void draw_line(drawsurface *ds, int x1, int y1, int x2, int y2)
  66. {
  67.     int tmp, x, y, ww;
  68.     unsigned short *d;
  69.     
  70.     ww = ds->ww;
  71.  
  72.     if (x2 < x1) {
  73.         tmp = x1;
  74.         x1 = x2;
  75.         x2 = tmp;
  76.         
  77.         tmp = y1;
  78.         y1 = y2;
  79.         y2 = tmp;
  80.     }
  81.     
  82.     if (y1 == y2) {
  83.         d = &ds->d[ww * y1];
  84.         for (; x1 <= x2; x1++) {
  85.             d[x1 >> 4] |= 1 << (15 - (x1 & 15));
  86.         }
  87.         return;
  88.     }
  89.     
  90.     if (x1 == x2) {
  91.         if (y2 < y1) {
  92.             for (; y2 <= y1; y2++) {
  93.                 d = &ds->d[ww * y2];
  94.                 d[x1 >> 4] |= 1 << (15 - (x1 & 15));
  95.             }
  96.         } else {
  97.             for (; y1 <= y2; y1++) {
  98.                 d = &ds->d[ww * y1];
  99.                 d[x1 >> 4] |= 1 << (15 - (x1 & 15));
  100.             }
  101.         }
  102.         return;
  103.     }
  104.     
  105.     if (y2 < y1) {
  106.         if (y1 - y2 < x2 - x1) {
  107.             for (x = x1; x <= x2; x++) {
  108.                 tmp = ((x - x1) * (y2 - y1) + (x2 - x1)/2) / (x2 - x1) + y1;
  109.                 d = &ds->d[ww * tmp];
  110.                 d[x >> 4] |= 1 << (15 - (x & 15));
  111.             }
  112.         } else {
  113.             for (y = y1; y >= y2; y--) {
  114.                 tmp = ((y - y1) * (x2 - x1) + (y2 - y1)/2) / (y2 - y1) + x1;
  115.                 d = &ds->d[ww * y];
  116.                 d[tmp >> 4] |= 1 << (15 - (tmp & 15));
  117.             }
  118.         }
  119.     } else {
  120.         if (y2 - y1 < x2 - x1) {
  121.             for (x = x1; x <= x2; x++) {
  122.                 tmp = ((x - x1) * (y2 - y1) + (x2 - x1)/2) / (x2 - x1) + y1;
  123.                 d = &ds->d[ww * tmp];
  124.                 d[x >> 4] |= 1 << (15 - (x & 15));
  125.             }
  126.         } else {
  127.             for (y = y1; y <= y2; y++) {
  128.                 tmp = ((y - y1) * (x2 - x1) + (y2 - y1)/2) / (y2 - y1) + x1;
  129.                 d = &ds->d[ww * y];
  130.                 d[tmp >> 4] |= 1 << (15 - (tmp & 15));
  131.             }
  132.         }
  133.     }
  134. }
  135.  
  136. void undraw_line(drawsurface *ds, int x1, int y1, int x2, int y2)
  137. {
  138.     int tmp, x, y, ww;
  139.     unsigned short *d;
  140.     
  141.     ww = ds->ww;
  142.  
  143.     if (x2 < x1) {
  144.         tmp = x1;
  145.         x1 = x2;
  146.         x2 = tmp;
  147.         
  148.         tmp = y1;
  149.         y1 = y2;
  150.         y2 = tmp;
  151.     }
  152.     
  153.     if (y1 == y2) {
  154.         d = &ds->d[ww * y1];
  155.         for (; x1 <= x2; x1++) {
  156.             d[x1 >> 4] &=~ (1 << (15 - (x1 & 15)));
  157.         }
  158.         return;
  159.     }
  160.     
  161.     if (x1 == x2) {
  162.         if (y2 < y1) {
  163.             for (; y2 <= y1; y2++) {
  164.                 d = &ds->d[ww * y2];
  165.                 d[x1 >> 4] &=~ (1 << (15 - (x1 & 15)));
  166.             }
  167.         } else {
  168.             for (; y1 <= y2; y1++) {
  169.                 d = &ds->d[ww * y1];
  170.                 d[x1 >> 4] &=~ (1 << (15 - (x1 & 15)));
  171.             }
  172.         }
  173.         return;
  174.     }
  175.     
  176.     if (y2 < y1) {
  177.         if (y1 - y2 < x2 - x1) {
  178.             for (x = x1; x <= x2; x++) {
  179.                 tmp = ((x - x1) * (y2 - y1) + (x2 - x1)/2) / (x2 - x1) + y1;
  180.                 d = &ds->d[ww * tmp];
  181.                 d[x >> 4] &=~ (1 << (15 - (x & 15)));
  182.             }
  183.         } else {
  184.             for (y = y1; y >= y2; y--) {
  185.                 tmp = ((y - y1) * (x2 - x1) + (y2 - y1)/2) / (y2 - y1) + x1;
  186.                 d = &ds->d[ww * y];
  187.                 d[tmp >> 4] &=~ (1 << (15 - (tmp & 15)));
  188.             }
  189.         }
  190.     } else {
  191.         if (y2 - y1 < x2 - x1) {
  192.             for (x = x1; x <= x2; x++) {
  193.                 tmp = ((x - x1) * (y2 - y1) + (x2 - x1)/2) / (x2 - x1) + y1;
  194.                 d = &ds->d[ww * tmp];
  195.                 d[x >> 4] &=~ (1 << (15 - (x & 15)));
  196.             }
  197.         } else {
  198.             for (y = y1; y <= y2; y++) {
  199.                 tmp = ((y - y1) * (x2 - x1) + (y1 - y2)/2) / (y1 - y2) + x1;
  200.                 d = &ds->d[ww * y];
  201.                 d[tmp >> 4] &=~ (1 << (15 - (tmp & 15)));
  202.             }
  203.         }
  204.     }
  205. }
  206.  
  207. void clear_circle(drawsurface *ds, int x, int y, int r)
  208. {
  209.     int i, dx;
  210.     
  211.     for (i = y - r; i <= y + r; i++) {
  212.         dx = (int)sqrt((float)(r * r - (i - y) * (i - y)));
  213.         
  214.         undraw_line(ds, x - dx, i, x + dx, i);
  215.     }
  216. }
  217.  
  218. void draw_radius(drawsurface *d1, drawsurface *d2, int x, int y, int r, double theta)
  219. {
  220.     int x2, y2, dx, dy;
  221.     double rcos, rsin;
  222.     
  223.     rcos = r * cos(theta);
  224.     rsin = r * sin(theta);
  225.     
  226.     x2 = (int)rcos + x;
  227.     y2 = -(int)rsin + y;
  228.  
  229.     if (abs(rsin) > abs(rcos)) {
  230.         dx = 1;
  231.         dy = 0;
  232.     } else {
  233.         dx = 0;
  234.         dy = 1;
  235.     }
  236.     
  237.     draw_line(d1, x + dx, y + dy, x2 + dx, y2 + dy);
  238.     undraw_line(d2, x + dx, y + dy, x2 + dx, y2 + dy);
  239.     
  240.     draw_line(d2, x, y, x2, y2);
  241.     undraw_line(d1, x, y, x2, y2);
  242. }
  243.  
  244. void clear_clock(struct DiskObject *dobj)
  245. {
  246.     struct Gadget *g;
  247.     struct Image *i1, *i2;
  248.     drawsurface d1a, d1b, d2a, d2b;
  249.         
  250.     g = &dobj->do_Gadget;
  251.     i1 = (struct Image *)g->GadgetRender;
  252.     i2 = (struct Image *)g->SelectRender;
  253.     
  254.     d1a.width = i1->Width;
  255.     d1a.height = i1->Height;
  256.     d1a.ww = (i1->Width + 15) / 16;
  257.     
  258.     d2a.width = i2->Width;
  259.     d2a.height = i2->Height;
  260.     d2a.ww = (i2->Width + 15) / 16;
  261.     
  262.     d1b = d1a;
  263.     d2b = d2a;
  264.     
  265.     d1a.d = i1->ImageData;
  266.     d2a.d = i2->ImageData;
  267.     
  268.     d1b.d = d1a.d + d1a.height * d1a.ww;
  269.     d2b.d = d2a.d + d2a.height * d2a.ww;
  270.     
  271.     clear_circle(&d1a, d1a.width / 2, d1a.height / 2, 15);
  272.     clear_circle(&d1b, d1b.width / 2, d1b.height / 2, 15);
  273.  
  274.     clear_circle(&d2a, d2a.width / 2 + 1, d2a.height / 2 + 1, 15);
  275.     clear_circle(&d2b, d2b.width / 2 + 1, d2b.height / 2 + 1, 15);
  276. }
  277.  
  278. void draw_time(struct timerequest *tr, struct DiskObject *dobj)
  279. {
  280.     int hours, mins;
  281.     struct Gadget *g;
  282.     struct Image *i1, *i2;
  283.     drawsurface d1a, d1b, d2a, d2b;
  284.     double mtheta, htheta;
  285.         
  286.     mins = (tr->tr_time.tv_secs / 60) % 60;
  287.     hours = (tr->tr_time.tv_secs / 60) % 720;
  288.     
  289.     g = &dobj->do_Gadget;
  290.     i1 = (struct Image *)g->GadgetRender;
  291.     i2 = (struct Image *)g->SelectRender;
  292.     
  293.     d1a.width = i1->Width;
  294.     d1a.height = i1->Height;
  295.     d1a.ww = (i1->Width + 15) / 16;
  296.     
  297.     d2a.width = i2->Width;
  298.     d2a.height = i2->Height;
  299.     d2a.ww = (i2->Width + 15) / 16;
  300.     
  301.     d1b = d1a;
  302.     d2b = d2a;
  303.     
  304.     d1a.d = i1->ImageData;
  305.     d2a.d = i2->ImageData;
  306.     
  307.     d1b.d = d1a.d + d1a.height * d1a.ww;
  308.     d2b.d = d2a.d + d2a.height * d2a.ww;
  309.     
  310.     mtheta = PID2 - 2 * PI * mins / 60;
  311.     htheta = PID2 - 2 * PI * hours / 720;
  312.  
  313.     clear_circle(&d1a, d1a.width / 2, d1a.height / 2, 15);
  314.     clear_circle(&d1b, d1b.width / 2, d1b.height / 2, 15);
  315.  
  316.     clear_circle(&d2a, d2a.width / 2 + 1, d2a.height / 2 + 1, 15);
  317.     clear_circle(&d2b, d2b.width / 2 + 1, d2b.height / 2 + 1, 15);
  318.  
  319.     draw_radius(&d1a, &d1b, d1b.width / 2, d1b.height / 2, 14, mtheta);
  320.     draw_radius(&d1a, &d1b, d1b.width / 2, d1b.height / 2, 8, htheta);
  321.  
  322.     draw_radius(&d2a, &d2b, d1b.width / 2 + 1, d1b.height / 2 + 1, 14, mtheta);
  323.     draw_radius(&d2a, &d2b, d1b.width / 2 + 1, d1b.height / 2 + 1, 8, htheta);
  324. }
  325.  
  326. #define DIE_MESSAGE 0xaaff
  327.  
  328. void main(int argc, char **argv)
  329. {
  330.     struct DiskObject *dobj;
  331.     struct MsgPort *timeport;
  332.     struct timerequest *timer, *intr;
  333.     boolean quit = false;
  334.     
  335.     IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
  336.     if (!IntuitionBase) {
  337.         exit(15);
  338.     }
  339.     
  340.     if (timeport = FindPort("wb_clock")) {
  341.         timer = (struct timerequest *)CreateExtIO(timeport, sizeof(*timer));
  342.         if (!timer) {
  343.             error("Can't create time request");
  344.             CloseLibrary((struct Library *)IntuitionBase);
  345.             exit(10);
  346.         }
  347.         timer->tr_node.io_Command = DIE_MESSAGE;
  348.         PutMsg(timeport, (struct Message *)timer);
  349.         CloseLibrary((struct Library *)IntuitionBase);
  350.         exit(0);
  351.     }
  352.     
  353.     IconBase = OpenLibrary("icon.library", 0);
  354.     if (!IconBase) {
  355.         error("Can't open icon.library");
  356.         CloseLibrary((struct Library *)IntuitionBase);
  357.         exit(10);
  358.     }
  359.     
  360.     WorkbenchBase = OpenLibrary("workbench.library", 0);
  361.     if (WorkbenchBase) {
  362.         if (argc) dobj = GetDiskObject(argv[0]);
  363.         else dobj = wb_disk_object((struct WBStartup *)argv);
  364.         
  365.         if (dobj) {
  366.             timeport = CreatePort("wb_clock", 0);
  367.             if (timeport) {
  368.                 timer = (struct timerequest *)CreateExtIO(timeport, sizeof(*timer));
  369.                 if (timer) {
  370.                     if (OpenDevice("timer.device", UNIT_VBLANK, (void *)timer, 0) == 0) {
  371.                         timer->tr_node.io_Command = TR_ADDREQUEST;
  372.                         timer->tr_time.tv_secs = 5;
  373.                         timer->tr_time.tv_micro = 0;
  374.                         
  375.                         SendIO((void *)timer);
  376.                         while (1) {
  377.                             Wait(1 << timeport->mp_SigBit);
  378.                             
  379.                             while (intr = (struct timerequest *)GetMsg(timeport)) {
  380.                                 if (intr->tr_node.io_Command == DIE_MESSAGE) {
  381.                                     quit = true;
  382.                                     DeleteExtIO((void *)intr);
  383.                                     AbortIO((void *)timer);
  384.                                     continue;
  385.                                 }
  386.                                 
  387.                                 if (quit) {
  388.                                     clear_clock(dobj);
  389.                                     
  390.                                     if (argc) PutDiskObject(argv[0], dobj);
  391.                                     else wb_put_disk_object((struct WBStartup *)argv, dobj);
  392.                                     
  393.                                     error("Exiting ...");
  394.                                     goto quit_loop;
  395.                                 }
  396.                                 
  397.                                 timer->tr_node.io_Command = TR_GETSYSTIME;
  398.                                 DoIO((void *)timer);
  399.                                 
  400.                                 draw_time(timer, dobj);
  401.                                 
  402.                                 if (argc) PutDiskObject(argv[0], dobj);
  403.                                 else wb_put_disk_object((struct WBStartup *)argv, dobj);
  404.  
  405.                                 timer->tr_node.io_Command = TR_ADDREQUEST;
  406.                                 timer->tr_time.tv_secs = 60 - timer->tr_time.tv_secs % 60;
  407.                                 timer->tr_time.tv_micro = 0;
  408.                                 SendIO((void *)timer);
  409.                             }
  410.                         }
  411.             quit_loop:
  412.                         CloseDevice((void *)timer);
  413.                     } else error("Can't open timer.device");
  414.                     DeleteExtIO((void *)timer);
  415.                 } else error("Can't create timer request");
  416.                 DeletePort(timeport);
  417.             } else error("Can't create port");
  418.             FreeDiskObject(dobj);
  419.         } else error("Can't get disk object");
  420.         CloseLibrary(WorkbenchBase);
  421.     } else error("Can't open workbench.library");
  422.     
  423.     CloseLibrary(IconBase);
  424.     CloseLibrary((struct Library *)IntuitionBase);
  425. }
  426.  
  427.